package pers.vic.boot.security.shiro;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @description: 移除URL后的sessionId；或者分号  或者;jsessionid=
 * @author Vic.xu
 */
public class RemoveUrlSessionFilter implements Filter {

    /**
     * @see InvalidRequestFilter.SEMICOLON 分号
     */
    public static List<String> SEMICOLON = Collections.unmodifiableList(Arrays.asList(";", "%3b", "%3B"));

    /**url中包含;jsessionid= 则直接删除后面的*/
    public static String INVALID_JSESSIONID = ";jsessionid=";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // skip non-http requests
        if (!(request instanceof HttpServletRequest)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // clear session if session id in URL
        if (httpRequest.isRequestedSessionIdFromURL()) {
            HttpSession session = httpRequest.getSession();
            if (session != null) {
                session.invalidate();
            }
        }

        // wrap response to remove URL encoding
        HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(httpResponse) {
            @Override
            public String encodeURL(String url) {
                return url;
            }
        };
        HttpServletRequestWrapper httpServletRequestWrapper = new HttpServletRequestWrapper(httpRequest) {
            @Override
            public String getRequestURI() {

                return rewriteUri(super.getRequestURI());
            }

        };


        // process next request in chain
        chain.doFilter(httpServletRequestWrapper, wrappedResponse);
    }

    /**
     * 如果以分号结尾 则删除分号; 如果包含;jsessionid  则删除
     */
    private String rewriteUri(String uri) {
        //非get 请求暂且无视
        if (uri == null) {
            return uri;
        }
        for (String s : SEMICOLON) {
            if (uri.endsWith(s)) {
                uri = uri.substring(0, uri.lastIndexOf(s));
            }
        }
        //  删除;jsessionid=5C88446AF1421AC52F550AEEB420BF0E
        if (uri.toLowerCase().contains(INVALID_JSESSIONID)) {
            uri = uri.substring(0, uri.toLowerCase().lastIndexOf(INVALID_JSESSIONID));
        }

        return uri;

    }
}
